webpack 常见问题精要(要点摘要)
以下为常见问题的陈述思路,陈述时可按「定义 → 差异 → 举例 → 踩坑」展开;与 Vite 对比见 [插件与构建对比](../vite/05、插件·Vitest·与 webpack 对比.md)。
1. Loader 和 Plugin 的区别?
- Loader:针对单个文件的转换链,在模块解析阶段把非 JS 资源变成 webpack 可消费的模块(一对多链式,自右向左执行)。
- Plugin:基于 Tapable 钩子,贯穿编译全流程(初始化、编译、输出、资源处理),适合做压缩、生成 HTML、拷贝、环境变量注入等横切能力。
- 一句话:Loader 转文件内容;Plugin 扩展构建流程。
2. 说说 webpack 的构建流程(简化)
- 读取配置,初始化 Compiler。
- 从 entry 递归解析依赖,生成 Module 图。
- Loader 转换各类模块;Plugin 在各钩子介入。
- Seal 阶段生成 chunk,优化分包。
- Emit 写出 assets;生成 Source Map(若配置)。
无需死记全钩子名,能说清「依赖图 → chunk → 输出」即可。
3. hash、chunkhash、contenthash 适用场景?
[fullhash]:整次构建相同则 hash 相同;一改全变,不利于长期缓存。[chunkhash]:同一 chunk 内容变才变;适合按 chunk 缓存。[contenthash]:按文件内容生成;CSS/JS 增量更新时常用,缓存命中率更好。
扩展:CDN 缓存策略与文件名指纹配合。
4. HMR(热模块替换)大致原理?
开发模式下保留运行时模块接口,模块更新后由 runtime 拉取新模块并替换旧模块回调,无需整页刷新;依赖 webpack-dev-server 与模块上的 HMR API。若写到「监听文件 → websocket 通知 → 增量更新」也可得分。
5. Tree Shaking 何时生效?为何有时摇不掉?
- 需要 ESM + 生产优化;
sideEffects标注错误会导致保守打包。 - CommonJS、
eval、动态难以静态分析的写法会削弱摇树效果。
6. babel-loader 在 webpack 里干什么?
把 ESNext/TS/JSX 转成目标环境可运行的语法(与 preset-env、targets 配合);通常 exclude: /node_modules/,除非要对依赖做特殊转译。
7. Webpack 5 的 Asset Modules 是什么?
用 type: 'asset' / asset/resource / asset/inline / asset/source 替代以往 file/url/raw-loader 的常见用法,由 webpack 内置处理静态资源与大小阈值内联策略。
8. Code Splitting 有哪些手段?
动态 import()、多入口、splitChunks、懒加载路由;目标是「首屏小、按需加载」。
9. 与 Vite 相比,webpack 的典型差异(一句话版)
- 开发:webpack 往往先打 bundle(dev-server 内存),冷启动与大规模项目下更易慢;Vite 开发态以原生 ESM + 依赖预构建为主。
- 生产:webpack 自有一套打包优化;Vite 生产多用 Rollup。
展开见 [Vite 插件与对比](../vite/05、插件·Vitest·与 webpack 对比.md)。
